package com.gome.boot.config.mongo;

import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Mongodb基础配置.
 *
 * @author baoxiufeng
 */
public abstract class BaseMongoConfig {

    /**
     * 日志操作对象
     */
    protected Logger logger = LoggerFactory.getLogger(BaseMongoConfig.class);

    private static final String KEY_MONGO_ADDRESS = "mongo.hostAndPort";
    private static final String KEY_MONGO_DBNAME = "mongo.dbName";
    private static final String KEY_MONGO_USERNAME = "mongo.username";
    private static final String KEY_MONGO_PASSWORD = "mongo.password";

    @Autowired
    protected Environment env;

    /**
     * 获取默认类型的Mongo客户端工具.
     *
     * @return Mongo客户端工具类
     */
    protected MongoClient getMongoClient() {
        return getMongoClient(null);
    }

    /**
     * 获取默认类型的Mongo客户端操作模板.
     *
     * @return Mongo客户端操作模板
     */
    protected MongoTemplate getMongoTemplate() {
        return getMongoTemplate(null);
    }

    /**
     * 获取指定类型的Mongo客户端操作模板.
     *
     * @param type Mongo数据库类型
     * @return Mongo客户端操作模板
     */
    protected MongoTemplate getMongoTemplate(String type) {
        MongoClient mongoClient = getMongoClient(type);
        if (mongoClient != null) {
            return new MongoTemplate(mongoClient, mongoClient.getCredentialsList().get(0).getSource());
        }
        return null;
    }

    /**
     * 获取指定类型的Mongo客户端工具类.
     *
     * @param type Mongo数据库类型
     * @return Mongo客户端工具
     */
    protected MongoClient getMongoClient(String type) {
        String address = null;
        String dbName = null;
        String username = null;
        String password = null;
        if (type == null) {
            address = env.getProperty(KEY_MONGO_ADDRESS, "");
            dbName = env.getRequiredProperty(KEY_MONGO_DBNAME);
            username = env.getRequiredProperty(KEY_MONGO_USERNAME);
            password = env.getRequiredProperty(KEY_MONGO_PASSWORD);
        } else {
            address = env.getProperty(type + "." + KEY_MONGO_ADDRESS, "");
            dbName = env.getRequiredProperty(type + "." + KEY_MONGO_DBNAME);
            username = env.getRequiredProperty(type + "." + KEY_MONGO_USERNAME);
            password = env.getRequiredProperty(type + "." + KEY_MONGO_PASSWORD);
        }
        // 所有的mongodb地址
        String[] mongoAddresses = address.split(",");
        if (mongoAddresses == null || mongoAddresses.length < 1) {
            logger.error("Server Address Is Null(服务器列表为空)");
            return null;
        }
        // 服务集群列表
        List<ServerAddress> addresses = new ArrayList<>(mongoAddresses.length);
        for (String mongoAddress : mongoAddresses) {
            try {
                // 主机和端口号解析
                String[] hostAndPort = mongoAddress.split(":");
                addresses.add(new ServerAddress(hostAndPort[0], Integer.valueOf(hostAndPort[1])));
            } catch (Exception e) {
                logger.error("Address Setting Error(服务器列表设置错误)", e);
            }
        }
        // 生成客户端
        return new MongoClient(addresses, Arrays.asList(MongoCredential.createCredential(username, dbName, password.toCharArray())));
    }
}
